/*
 * This file is part of the GUI_SDK.
 *
 * Copyright (c) 2019-2019 Link-Card.Co.Ltd. All rights reserved.
 *
 * Authors:
 *    JiangYong <1556631285@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * 'Software'), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Function:  function entry.
 * Created on: 2019-10-05
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <stdbool.h>

#include "menu.h"
#include "event.h"
#include "key.h"
#include "v4l2overlay.h"

#include "log2file.h"

icon_normal_t normal;

static unsigned int bExit = 0;

static void onStop(int sig)
{
	printf("exit!!!\n");
	bExit = 1;
	sleep(1);
	exit(0);
}

unsigned int onExit()
{
	return (!bExit);
}

static void update_gui_normal(UICtx_t *pobj)
{
	SDL_RenderClear((SDL_Renderer *)pobj->pgui);
	update_menu_normal(&normal, pobj);
}

static void update_gui_search_wifi(UICtx_t *pobj)
{
	SDL_RenderClear((SDL_Renderer *)pobj->pgui);
	update_menu_search_wifi(&normal, pobj);
}

static void update_gui_password(UICtx_t *pobj)
{
	SDL_RenderClear((SDL_Renderer *)pobj->pgui);
	update_menu_password(&normal, pobj);
}

static void update_gui_ver_info(UICtx_t *pobj)
{
	SDL_RenderClear((SDL_Renderer *)pobj->pgui);
	update_menu_ver_info(&normal, pobj);
}

static void update_gui_update(UICtx_t *pobj)
{
	SDL_RenderClear((SDL_Renderer *)pobj->pgui);
	update_menu_update(&normal, pobj);
}

/*
	handle_gui
	显示处理中心
	
	输入事件:   
	           是否需要刷新GUI界面
	输出事件:
	            无
*/
void handle_gui(UICtx_t * pobj, int actions)
{	
	SDL_Renderer *renderer = (SDL_Renderer *)pobj->pgui;

	if (EGUI_INIT ==  actions) {
		//初始化屏幕
		normal.renderer = renderer;
	} else if (EGUI_UPDATE == actions) {
		switch(pobj->curid)
		{
		case id_normal:
			update_gui_normal(pobj);
			break;
		case id_search_wifi:
			update_gui_search_wifi(pobj);
			break;
		case id_password:
			update_gui_password(pobj);
			break;
		case id_ver_info:
			update_gui_ver_info(pobj);
			break;
		case id_update:
			update_gui_update(pobj);
			break;
		}
		// flip the backbuffer
		// this means that everything that we prepared behind the screens is actually shown
		//SDL_RenderPresent(renderer);
	}
	return;
}

static unsigned int bIsDaemon = 0;

static void print_usage(void)
{
	fprintf(stderr,	"Usage:\n"
				"    sdl [-D] \n"
				"Options:\n"
				"    -D                 Run as Daemon\n"
				"    -h                 This help\n");
}
/**************************************************
*
*
***************************************************/
int main (int argc, char *argv[]) 
{
	int i;
	while ((i=getopt(argc, argv, "Dh")) != -1)
	{
		switch(i)
		{
		case 'D':
			bIsDaemon = 1;
			break;
		case 'h':
		default:
			print_usage();
			exit(0);
		}
	}
	
	/* run as Daemon*/
	if (bIsDaemon) {
		daemon(1, 1);//主要用于希望脱离控制台，以守护进程形式在后台运行的程序。
	}
	
	// variable declarations
	SDL_Window *win = NULL;
	SDL_Renderer *renderer = NULL;

	//! register signal
	signal(SIGTERM, onStop);
	signal(SIGINT, onStop);

	//设置SDL的环境变量
	//https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlenvvars.html
	setenv("SDL_VIDEODRIVER","dummy",0);
	setenv("SDL_FBACCEL","0",0);
	setenv("SDL_FBDEV","/dev/fb2",0);
	setenv("SDL_VIDEO_YUV_DIRECT","1",0);
	//setenv("SDL_VIDEO_DUMMY_SAVE_FRAMES","1",0);

	// Initialize SDL.
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		printf("SDL_Init failed: %s\n", SDL_GetError());
		return -1;
	}

	if(TTF_Init() < 0) {
       	printf("TTF_Init failed: %s\n", TTF_GetError());
		return -1;
	}
	
	// create the window and renderer
	// note that the renderer is accelerated
	win = SDL_CreateWindow("Image Loading", 0, 0, OSD_WIDTH, OSD_HEIGHT, 0);
	renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE);
	if(NULL == renderer) {
       	printf("SDL_CreateRenderer: %s\n", SDL_GetError());
		return -1;
	}

//	SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
//	SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff);
	UICtx_t *pdev = getUICtx();
	Init_UICtx(pdev,0);
	pdev->pgui = renderer;
	
	//加载资源，比较耗时间
	//避免运行过程闪屏
	handle_gui(pdev, EGUI_INIT);
	handle_gui(pdev, EGUI_UPDATE);

	SDL_v4l2_driver_init(win);
	SDL_v4l2_RenderMemory(win, 0);   //避免出现花屏
	SDL_v4l2_RenderMemory(win, 1);   //避免出现花屏
	SDL_v4l2_RenderMemory(win, 2);   //避免出现花屏
	SDL_v4l2_start();

	create_keys_thread();

	// main loop
	while (!bExit) 
	{	
		// event handling
		SDL_Event e;
		if (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) {
				break;
			} else if (e.type == SDL_KEYUP) {
				eKeyVal key = e.key.keysym.sym;
				if(handle_event(getUICtx(), key) > 0) {
					if (0 == SDL_v4l2_RenderMem_Pull(win)) {
						handle_gui(getUICtx(), 1);
						SDL_v4l2_RenderMem_Push(win);
					}
				}
			}
		} else {
			usleep(200 * 1000);
		}
	}

	SDL_v4l2_driver_deinit();
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(win);
	return 0;
}